์คํธ๋ฆผ ๋ฒํผ๋ง์ ๋ํ ๊น์ด ์๋ ํ๊ตฌ๋ฅผ ํตํด ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ์์๋ณด์ธ์. ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ๋ฆ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ฑ๋ฅ์ ์ต์ ํํ๋ฉฐ, ๊ฒฌ๊ณ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ: ๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง ๋ง์คํฐํ๊ธฐ
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์ ์ด์์ ๋๋ค. ๋ฐ์ดํฐ ์คํธ๋ฆผ ์ฒ๋ฆฌ, ๋์ฉ๋ ํ์ผ ์ฒ๋ฆฌ, ์ค์๊ฐ ์ ๋ฐ์ดํธ ๊ด๋ฆฌ ๋ฑ์ ๋ชจ๋ ํจ์จ์ ์ธ ๋น๋๊ธฐ ์์ ์ ์์กดํฉ๋๋ค. ES2018์ ๋์ ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ํ์ค๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ํ์ง๋ง ๋๋ก๋ ์ด๋ฌํ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋ํด ๋ ๋ง์ ์ ์ด๊ฐ ํ์ํ ๋๊ฐ ์์ต๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ ์ปค์คํ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ํตํด ๊ตฌํ๋๋ ์คํธ๋ฆผ ๋ฒํผ๋ง์ด ๋งค์ฐ ์ค์ํด์ง๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ๋ ๋ฌด์์ธ๊ฐ?
๋ฒํผ๋ง์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ์ ๋ํด ๊ฐ๋จํ ๋ณต์ตํด ๋ณด๊ฒ ์ต๋๋ค:
- ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ(Async Iterators): ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ๋กํ ์ฝ์ ๋ฐ๋ฅด๋ ๊ฐ์ฒด๋ก, IteratorResult ๊ฐ์ฒด(
{ value: any, done: boolean })๋ก ํด์๋๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋next()๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค. - ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ(Async Generators):
async function*๊ตฌ๋ฌธ์ผ๋ก ์ ์ธ๋ ํจ์์ ๋๋ค. ์ด๋ค์ ์๋์ผ๋ก ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํ๋กํ ์ฝ์ ๊ตฌํํ๋ฉฐ ๋น๋๊ธฐ์ ์ธ ๊ฐ์ ์์ฑ(yield)ํ ์ ์๊ฒ ํด์ค๋๋ค.
๋ค์์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ์ ๊ฐ๋จํ ์์์ ๋๋ค:
async function* generateNumbers(count) {
for (let i = 0; i < count; i++) {
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate async operation
yield i;
}
}
(async () => {
for await (const number of generateNumbers(5)) {
console.log(number);
}
})();
์ด ์ฝ๋๋ ๊ฐ ์ซ์ ์ฌ์ด์ 500ms์ ์ง์ฐ์ ๋๊ณ 0๋ถํฐ 4๊น์ง์ ์ซ์๋ฅผ ์์ฑํฉ๋๋ค. for await...of ๋ฃจํ๋ ์ด ๋น๋๊ธฐ ์คํธ๋ฆผ์ ์๋นํฉ๋๋ค.
์คํธ๋ฆผ ๋ฒํผ๋ง์ ํ์์ฑ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์๋นํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง๋ง, ๋ณธ์ง์ ์ผ๋ก ๋ฒํผ๋ง ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ ์์ต๋๋ค. ๋ฒํผ๋ง์ ๋ค์ํ ์๋๋ฆฌ์ค์์ ํ์์ ์ ๋๋ค:
- ์๋ ์ ํ(Rate Limiting): ์๋ ์ ํ์ด ์๋ ์ธ๋ถ API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ๋ฅผ ์์ํด ๋ณด์ธ์. ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ์์ฒญ์ ๋ชจ์์ ์ผ๊ด์ ์ผ๋ก ์ ์กํ์ฌ API์ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์์ ๋ฏธ๋์ด API๋ ๋ถ๋น ์ฌ์ฉ์ ํ๋กํ ์์ฒญ ์๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ ๋ณํ(Data Transformation): ๋ณต์กํ ๋ณํ์ ์ํํ๊ธฐ ์ ์ ํน์ ์์ ํญ๋ชฉ์ ๋์ ํด์ผ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋๋ ํจํด์ ์๋ณํ๊ธฐ ์ํด ์ผ์ ๋ฒ์์ ๊ฐ์ ๋ถ์ํด์ผ ํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ(Error Handling): ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ์คํจํ ์์ ์ ๋ ํจ๊ณผ์ ์ผ๋ก ์ฌ์๋ํ ์ ์์ต๋๋ค. ๋คํธ์ํฌ ์์ฒญ์ด ์คํจํ๋ฉด ๋ฒํผ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๋์ค์ ๋ค์ ์๋ํ๊ธฐ ์ํด ํ์ ๋ค์ ๋ฃ์ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ต์ ํ(Performance Optimization): ๋ฐ์ดํฐ๋ฅผ ๋ ํฐ ๋ฉ์ด๋ฆฌ๋ก ์ฒ๋ฆฌํ๋ฉด ๊ฐ๋ณ ์์ ์ ์ค๋ฒํค๋๋ฅผ ์ค์ฌ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ, ๊ฐ ํฝ์ ์ ๊ฐ๋ณ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ๋ณด๋ค ๋ ํฐ ๋ฉ์ด๋ฆฌ๋ก ์ฝ๊ณ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ์ ์์ต๋๋ค.
- ์ค์๊ฐ ๋ฐ์ดํฐ ์ง๊ณ(Real-time Data Aggregation): ์ค์๊ฐ ๋ฐ์ดํฐ(์: ์ฃผ์ ์์ธ, IoT ์ผ์ ํ๋ ๊ฐ)๋ฅผ ๋ค๋ฃจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ์๊ฐ ์ฐฝ์ ๊ฑธ์ณ ๋ฐ์ดํฐ๋ฅผ ์ง๊ณํ์ฌ ๋ถ์ํ๊ณ ์๊ฐํํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง ๊ตฌํํ๊ธฐ
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค. ์ปค์คํ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ๋ฅผ ๋ง๋๋ ๊ฒ์ ํฌํจํ์ฌ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. ์ปค์คํ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ
์ด ์ ๊ทผ ๋ฐฉ์์ ๊ธฐ์กด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๊ฐ์ธ๊ณ ๋ฒํผ๋ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํจ์๋ฅผ ๋ง๋๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๋ค์์ ๊ธฐ๋ณธ์ ์ธ ์์์ ๋๋ค:
async function* bufferAsyncIterator(source, bufferSize) {
let buffer = [];
for await (const item of source) {
buffer.push(item);
if (buffer.length >= bufferSize) {
yield buffer;
buffer = [];
}
}
if (buffer.length > 0) {
yield buffer;
}
}
// Example Usage
(async () => {
const numbers = generateNumbers(15); // Assuming generateNumbers from above
const bufferedNumbers = bufferAsyncIterator(numbers, 3);
for await (const chunk of bufferedNumbers) {
console.log("Chunk:", chunk);
}
})();
์ด ์์์์:
bufferAsyncIterator๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ(source)์bufferSize๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค.source๋ฅผ ๋ฐ๋ณตํ๋ฉด์buffer๋ฐฐ์ด์ ํญ๋ชฉ์ ๋์ ํฉ๋๋ค.buffer๊ฐbufferSize์ ๋๋ฌํ๋ฉด,buffer๋ฅผ ํ๋์ ์ฒญํฌ(chunk)๋ก ์์ฑ(yield)ํ๊ณbuffer๋ฅผ ์ฌ์ค์ ํฉ๋๋ค.- ์์ค๊ฐ ์์ง๋ ํ
buffer์ ๋จ์์๋ ๋ชจ๋ ํญ๋ชฉ์ ๋ง์ง๋ง ์ฒญํฌ๋ก ์์ฑ๋ฉ๋๋ค.
ํต์ฌ ๋ถ๋ถ ์ค๋ช :
async function* bufferAsyncIterator(source, bufferSize): ์ด ์ฝ๋๋ 'bufferAsyncIterator'๋ผ๋ ์ด๋ฆ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ํจ์๋ฅผ ์ ์ํฉ๋๋ค. ์ด ํจ์๋ 'source'(๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ)์ 'bufferSize'(๋ฒํผ์ ์ต๋ ํฌ๊ธฐ) ๋ ๊ฐ์ง ์ธ์๋ฅผ ๋ฐ์ต๋๋ค.let buffer = [];: ๋ฒํผ๋ง๋ ํญ๋ชฉ์ ๋ด์ ๋น ๋ฐฐ์ด์ ์ด๊ธฐํํฉ๋๋ค. ์ด ๋ฐฐ์ด์ ์ฒญํฌ๊ฐ ์์ฑ๋ ๋๋ง๋ค ์ฌ์ค์ ๋ฉ๋๋ค.for await (const item of source) { ... }: ์ดfor...await...of๋ฃจํ๋ ๋ฒํผ๋ง ๊ณผ์ ์ ํต์ฌ์ ๋๋ค.source๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐ๋ณตํ๋ฉฐ ํ ๋ฒ์ ํ๋์ ํญ๋ชฉ์ ๊ฐ์ ธ์ต๋๋ค.source๊ฐ ๋น๋๊ธฐ์ ์ด๋ฏ๋ก,awaitํค์๋๋ ๋ฃจํ๊ฐ ๊ฐ ํญ๋ชฉ์ด ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋๋ก ๋ณด์ฅํฉ๋๋ค.buffer.push(item);:source์์ ๊ฐ์ ธ์จ ๊ฐitem์buffer๋ฐฐ์ด์ ์ถ๊ฐ๋ฉ๋๋ค.if (buffer.length >= bufferSize) { ... }: ์ด ์กฐ๊ฑด๋ฌธ์buffer๊ฐ ์ต๋bufferSize์ ๋๋ฌํ๋์ง ํ์ธํฉ๋๋ค.yield buffer;: ๋ฒํผ๊ฐ ๊ฐ๋ ์ฐจ๋ฉด, ์ ์ฒดbuffer๋ฐฐ์ด์ด ๋จ์ผ ์ฒญํฌ๋ก ์์ฑ๋ฉ๋๋ค.yieldํค์๋๋ ํจ์์ ์คํ์ ์ผ์ ์ค์งํ๊ณ ์๋น์(์ฌ์ฉ ์์ ์for await...of๋ฃจํ)์๊ฒbuffer๋ฅผ ๋ฐํํฉ๋๋ค. ์ค์ํ ์ ์yield๊ฐ ํจ์๋ฅผ ์ข ๋ฃํ์ง ์๊ณ ์ํ๋ฅผ ๊ธฐ์ตํ๋ค๊ฐ ๋ค์ ๊ฐ์ด ์์ฒญ๋ ๋ ์ค๋จ๋ ์ง์ ๋ถํฐ ์คํ์ ์ฌ๊ฐํ๋ค๋ ๊ฒ์ ๋๋ค.buffer = [];: ๋ฒํผ๋ฅผ ์์ฑํ ํ, ๋ค์ ํญ๋ชฉ ์ฒญํฌ๋ฅผ ๋์ ํ๊ธฐ ์์ํ๋๋ก ๋น ๋ฐฐ์ด๋ก ์ฌ์ค์ ๋ฉ๋๋ค.if (buffer.length > 0) { yield buffer; }:for await...of๋ฃจํ๊ฐ ์๋ฃ๋ ํ(์ฆ,source์ ๋ ์ด์ ํญ๋ชฉ์ด ์์), ์ด ์กฐ๊ฑด๋ฌธ์buffer์ ๋จ์์๋ ํญ๋ชฉ์ด ์๋์ง ํ์ธํฉ๋๋ค. ๋ง์ฝ ์๋ค๋ฉด, ์ด ๋จ์ ํญ๋ชฉ๋ค์ด ๋ง์ง๋ง ์ฒญํฌ๋ก ์์ฑ๋ฉ๋๋ค. ์ด๋ ๋ฐ์ดํฐ ์์ค์ด ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
2. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ (์: RxJS)
RxJS์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฒํผ๋ง์ ํฌํจํ์ฌ ๋น๋๊ธฐ ์คํธ๋ฆผ ์์ ์ ์ํ ๊ฐ๋ ฅํ ์ฐ์ฐ์๋ฅผ ์ ๊ณตํฉ๋๋ค. RxJS๋ ๋ ๋ณต์กํ์ง๋ง ์คํธ๋ฆผ ์กฐ์์ ์ํ ํ๋ถํ ๊ธฐ๋ฅ ์ธํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
const { from, interval } = require('rxjs');
const { bufferCount } = require('rxjs/operators');
// Example using RxJS
(async () => {
const numbers = from(generateNumbers(15));
const bufferedNumbers = numbers.pipe(bufferCount(3));
bufferedNumbers.subscribe(chunk => {
console.log("Chunk:", chunk);
});
})();
์ด ์์์์:
from์ ์ฌ์ฉํ์ฌgenerateNumbers๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ก๋ถํฐ RxJS Observable์ ์์ฑํฉ๋๋ค.bufferCount(3)์ฐ์ฐ์๋ ์คํธ๋ฆผ์ ํฌ๊ธฐ 3์ ์ฒญํฌ๋ก ๋ฒํผ๋งํฉ๋๋ค.subscribe๋ฉ์๋๋ ๋ฒํผ๋ง๋ ์คํธ๋ฆผ์ ์๋นํฉ๋๋ค.
3. ์๊ฐ ๊ธฐ๋ฐ ๋ฒํผ ๊ตฌํํ๊ธฐ
๋๋ก๋ ํญ๋ชฉ ์๊ฐ ์๋ ์๊ฐ ์ฐฝ์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฒํผ๋งํด์ผ ํฉ๋๋ค. ์๊ฐ ๊ธฐ๋ฐ ๋ฒํผ๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
async function* timeBasedBufferAsyncIterator(source, timeWindowMs) {
let buffer = [];
let lastEmitTime = Date.now();
for await (const item of source) {
buffer.push(item);
const currentTime = Date.now();
if (currentTime - lastEmitTime >= timeWindowMs) {
yield buffer;
buffer = [];
lastEmitTime = currentTime;
}
}
if (buffer.length > 0) {
yield buffer;
}
}
// Example Usage:
(async () => {
const numbers = generateNumbers(10);
const timeBufferedNumbers = timeBasedBufferAsyncIterator(numbers, 1000); // Buffer for 1 second
for await (const chunk of timeBufferedNumbers) {
console.log("Time-based Chunk:", chunk);
}
})();
์ด ์์ ๋ ์ง์ ๋ ์๊ฐ ์ฐฝ(timeWindowMs)์ด ๊ฒฝ๊ณผํ ๋๊น์ง ํญ๋ชฉ์ ๋ฒํผ๋งํฉ๋๋ค. ํน์ ๊ธฐ๊ฐ์ ๋ํ๋ด๋ ๋ฐฐ์น๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ์๋๋ฆฌ์ค(์: ๋งค๋ถ ์ผ์ ํ๋
๊ฐ ์ง๊ณ)์ ์ ํฉํฉ๋๋ค.
๊ณ ๊ธ ๊ณ ๋ ค์ฌํญ
1. ์ค๋ฅ ์ฒ๋ฆฌ
๋น๋๊ธฐ ์คํธ๋ฆผ์ ๋ค๋ฃฐ ๋ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์์ ๊ณ ๋ คํ์ญ์์ค:
- ์ฌ์๋ ๋ฉ์ปค๋์ฆ: ์คํจํ ์์ ์ ๋ํ ์ฌ์๋ ๋ก์ง์ ๊ตฌํํฉ๋๋ค. ๋ฒํผ๋ ์ค๋ฅ ํ ์ฌ์ฒ๋ฆฌํด์ผ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ ์ ์์ต๋๋ค. `p-retry`์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์ค๋ฅ ์ ํ: ์์ค ์คํธ๋ฆผ์ ์ค๋ฅ๊ฐ ์๋น์์๊ฒ ์ฌ๋ฐ๋ฅด๊ฒ ์ ํ๋๋๋ก ํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ด์์
try...catch๋ธ๋ก์ ์ฌ์ฉํ์ฌ ์์ธ๋ฅผ ์ก๊ณ ๋ค์ ๋์ง๊ฑฐ๋ ์ค๋ฅ ์ํ๋ฅผ ์ ํธ๋ก ๋ณด๋ ๋๋ค. - ์ํท ๋ธ๋ ์ด์ปค ํจํด: ์ค๋ฅ๊ฐ ์ง์๋๋ฉด ์ฐ์์ ์ธ ์คํจ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ํท ๋ธ๋ ์ด์ปค ํจํด์ ๊ตฌํํ๋ ๊ฒ์ ๊ณ ๋ คํฉ๋๋ค. ์ด๋ ์์คํ ์ด ๋ณต๊ตฌ๋ ์ ์๋๋ก ์ผ์์ ์ผ๋ก ์์ ์ ์ค๋จํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
2. ์ญ์(Backpressure)
์ญ์์ ์๋น์๊ฐ ์์ฐ์์๊ฒ ์์ ์ด ๊ณผ๋ถํ ์ํ์ด๋ฉฐ ๋ฐ์ดํฐ ๋ฐฉ์ถ ์๋๋ฅผ ๋ฆ์ถฐ์ผ ํจ์ ์๋ฆฌ๋ ๋ฅ๋ ฅ์ ์๋ฏธํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ await ํค์๋๋ฅผ ํตํด ์๋น์๊ฐ ํ์ฌ ํญ๋ชฉ์ ์ฒ๋ฆฌํ ๋๊น์ง ์์ฐ์๋ฅผ ์ผ์ ์ค์ง์ํค๋ ๋ฐฉ์์ผ๋ก ๋ณธ์ง์ ์ธ ์ญ์์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ณต์กํ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ด ์๋ ์๋๋ฆฌ์ค์์๋ ๋ ๋ช
์์ ์ธ ์ญ์ ๋ฉ์ปค๋์ฆ์ด ํ์ํ ์ ์์ต๋๋ค.
๋ค์ ์ ๋ต๋ค์ ๊ณ ๋ คํด ๋ณด์ธ์:
- ์ ํ๋ ๋ฒํผ(Bounded Buffers): ๊ณผ๋ํ ๋ฉ๋ชจ๋ฆฌ ์๋น๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ ํํฉ๋๋ค. ๋ฒํผ๊ฐ ๊ฐ๋ ์ฐจ๋ฉด ์์ฐ์๋ฅผ ์ผ์ ์ค์งํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ (์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ์ ํจ๊ป) ๋ฒ๋ฆด ์ ์์ต๋๋ค.
- ์ ํธ ๋ณด๋ด๊ธฐ(Signaling): ์๋น์๊ฐ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ค๋น๊ฐ ๋์์ ๋ ์์ฐ์์๊ฒ ๋ช ์์ ์ผ๋ก ์๋ฆฌ๋ ์ ํธ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํฉ๋๋ค. ์ด๋ ํ๋ก๋ฏธ์ค์ ์ด๋ฒคํธ ์ด๋ฏธํฐ์ ์กฐํฉ์ ์ฌ์ฉํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
3. ์ทจ์(Cancellation)
์๋น์๊ฐ ๋น๋๊ธฐ ์์
์ ์ทจ์ํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋ฐ์ํ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ตฌ์ถํ๋ ๋ฐ ํ์์ ์
๋๋ค. AbortController API๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์ทจ์ ์ ํธ๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
async function* cancellableBufferAsyncIterator(source, bufferSize, signal) {
let buffer = [];
for await (const item of source) {
if (signal.aborted) {
break; // Exit the loop if cancellation is requested
}
buffer.push(item);
if (buffer.length >= bufferSize) {
yield buffer;
buffer = [];
}
}
if (buffer.length > 0 && !signal.aborted) {
yield buffer;
}
}
// Example Usage
(async () => {
const controller = new AbortController();
const { signal } = controller;
const numbers = generateNumbers(15);
const bufferedNumbers = cancellableBufferAsyncIterator(numbers, 3, signal);
setTimeout(() => {
controller.abort(); // Cancel after 2 seconds
console.log("Cancellation Requested");
}, 2000);
try {
for await (const chunk of bufferedNumbers) {
console.log("Chunk:", chunk);
}
} catch (error) {
console.error("Error during iteration:", error);
}
})();
์ด ์์์์ cancellableBufferAsyncIterator ํจ์๋ AbortSignal์ ๋ฐ์ต๋๋ค. ์ด ํจ์๋ ๊ฐ ๋ฐ๋ณต์์ signal.aborted ์์ฑ์ ํ์ธํ๊ณ ์ทจ์๊ฐ ์์ฒญ๋๋ฉด ๋ฃจํ๋ฅผ ์ข
๋ฃํฉ๋๋ค. ์๋น์๋ controller.abort()๋ฅผ ์ฌ์ฉํ์ฌ ์์
์ ์ค๋จํ ์ ์์ต๋๋ค.
์ค์ ์ฌ๋ก ๋ฐ ์ฌ์ฉ ์์
๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง์ด ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ด๋ป๊ฒ ์ ์ฉ๋ ์ ์๋์ง ๊ตฌ์ฒด์ ์ธ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
- ๋ก๊ทธ ์ฒ๋ฆฌ: ๋์ฉ๋ ๋ก๊ทธ ํ์ผ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค๊ณ ์์ํด ๋ณด์ธ์. ๋ก๊ทธ ํญ๋ชฉ์ ์ฒญํฌ๋ก ๋ฒํผ๋งํ ๋ค์ ๊ฐ ์ฒญํฌ๋ฅผ ๋ณ๋ ฌ๋ก ๋ถ์ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ก๊ทธ์์ ํจํด์ ํจ์จ์ ์ผ๋ก ์๋ณํ๊ณ , ์ด์์ ๊ฐ์งํ๋ฉฐ, ๊ด๋ จ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค.
- ์ผ์ ๋ฐ์ดํฐ ์์ง: IoT ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ผ์๋ ์ง์์ ์ผ๋ก ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์์ฑํฉ๋๋ค. ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ์๊ฐ ์ฐฝ์ ๊ฑธ์ณ ์ผ์ ํ๋ ๊ฐ์ ์ง๊ณํ ๋ค์ ์ง๊ณ๋ ๋ฐ์ดํฐ์ ๋ํ ๋ถ์์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋งค๋ถ ์จ๋ ํ๋ ๊ฐ์ ๋ฒํผ๋งํ ๋ค์ ํด๋น ๋ถ์ ํ๊ท ์จ๋๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค.
- ๊ธ์ต ๋ฐ์ดํฐ ์ฒ๋ฆฌ: ์ค์๊ฐ ์ฃผ์ ์์ธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ๋๋์ ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ์งง์ ๊ฐ๊ฒฉ์ผ๋ก ๊ฐ๊ฒฉ ์์ธ๋ฅผ ์ง๊ณํ ๋ค์ ์ด๋ ํ๊ท ๋๋ ๊ธฐํ ๊ธฐ์ ์งํ๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค.
- ์ด๋ฏธ์ง ๋ฐ ๋น๋์ค ์ฒ๋ฆฌ: ๋์ฉ๋ ์ด๋ฏธ์ง๋ ๋น๋์ค๋ฅผ ์ฒ๋ฆฌํ ๋ ๋ฒํผ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ ํฐ ์ฒญํฌ๋ก ์ฒ๋ฆฌํ ์ ์๋๋ก ํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋น๋์ค ํ๋ ์์ ๊ทธ๋ฃน์ผ๋ก ๋ฒํผ๋งํ ๋ค์ ๊ฐ ๊ทธ๋ฃน์ ๋ณ๋ ฌ๋ก ํํฐ๋ฅผ ์ ์ฉํ ์ ์์ต๋๋ค.
- API ์๋ ์ ํ: ์ธ๋ถ API์ ์ํธ ์์ฉํ ๋ ๋ฒํผ๋ง์ ์๋ ์ ํ์ ์ค์ํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ์์ฒญ์ ๋ฒํผ๋งํ ๋ค์ ์ผ๊ด์ ์ผ๋ก ์ ์กํ์ฌ API์ ์๋ ์ ํ์ ์ด๊ณผํ์ง ์๋๋ก ํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ, ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ, ๊ทธ๋ฆฌ๊ณ ์ปค์คํ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ์ ์๋ฆฌ๋ฅผ ์ดํดํจ์ผ๋ก์จ, ๋ณต์กํ ๋น๋๊ธฐ ์ํฌ๋ก๋๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ํจ์จ์ ์ด๊ณ ๊ฒฌ๊ณ ํ๋ฉฐ ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฒํผ๋ง์ ๊ตฌํํ ๋๋ ์ค๋ฅ ์ฒ๋ฆฌ, ์ญ์, ์ทจ์๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค. ๋์ฉ๋ ๋ก๊ทธ ํ์ผ์ ์ฒ๋ฆฌํ๋ , ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ , ์ธ๋ถ API์ ์ํธ ์์ฉํ๋ , ๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฒํผ๋ง์ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋ฐ์ ์ธ ๋ฐ์์ฑ์ ํฅ์์ํค๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ๋ ๊ณ ๊ธ ์คํธ๋ฆผ ์กฐ์ ๊ธฐ๋ฅ์ ์ํด RxJS์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ํ๋ ๊ฒ์ ๊ณ ๋ คํ๋, ๋ฒํผ๋ง ์ ๋ต์ ๋ํด ์ ๋ณด์ ์ ๊ฐํ ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ธฐ ์ํด ํญ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํดํ๋ ๊ฒ์ ์ฐ์ ์ํ์ญ์์ค.